#!/bin/bash
# ------------------------------------------------------------------------------
#
# SERPRO - Serviço Federal de Processamento de Dados - Regional Brasília
# Superintendência: CDSUT/SUPCD/CDSXB
#
# Nome do programa: cabecalho.ksh
#
# Site:
#
# Descrição abreviada de funcionalidade: Adiciona o cabeçalho padrão ao início
# de um script já criado ou inexistente.
# 
# Autor(es): Moacir da Cruz Souza Filho <moacir.souza-filho@serpro.gov.br>
# 
# Data de criação do programa: 27/02/2008
# 
# ------------------------------------------------------------------------------
# 
# Descrição detalhada de funcionalidade: A técnica HERE DOCUMENT é utilizada
# em conjunto com o comando cat para preencher um arquivo temporário com o 
# conteúdo do cabeçalho padrão. O arquivo passado como padrão para o script
# cabecalho.ksh recebe esses dados mantendo o conteúdo anterior inalterado.
# Se nenhum parâmetro for passado, é criado automaticamente um script vazio com
# o nome scriptNovoDDMMAAAA-hhmmss, onde os caracteres DD, MM, AAAA, hh, mm e
# ss representam, respectivamente, dia, mês, ano, hora, minuto e segundo em que
# cabecalho.ksh foi chamado.
#
# Exemplo(s):
#   $ ./cabecalho.ksh -a saida.ksh
#	#================================================
#	# Cabeçalho padrão da SUPCD criado para o script
#	# saida.ksh
#	#================================================
#	$
#
#	$ ./cabecalho.ksh -p saida.ksh
#	#!/usr/bin/ksh
#	# -----------------------------------------------------------------------
#	#
#	# SERPRO - Serviço Federal de Processamento de Dados - Regional Brasília
#	# Superintendência: CDSUT/SUPCD/CDSXB
#	#
#	# Nome do programa:
#	#
#	# Site:
#	(...)
#	$
#
#	$ ./cabecalho.ksh
#	#================================================
#	# Cabeçalho padrão da SUPCD criado para o script
#	# novoScript10102008-122525.ksh
#	#================================================
#	$ 
#
# ------------------------------------------------------------------------------
#
# Lista de Modificações
#
# Autor: Moacir da Cruz Souza Filho <moacir.souza-filho@serpro.gov.br>
#
# Versão 0.1 - 01/03/2008: 
#		- A quantidade de linhas apresentadas pelo head (linha 33) foi
# aumentada de 13 para 28.
#		- Adicionados testes para verificar se foi fornecido algum nome 
# para o script que vai receber o cabeçalho.
#
# Versão 0.2 - 02/03/2008:
#		- Melhoria da estrutura do cabeçalho, tornando-o mais informativo.
#
# Versão 0.3 - 04/07/2008:
#		- Criação da nova padronização de dados dentro do cabeçalho.
#		- Porções de código que não realizavam qualquer trabalho efetivo
# foram removidas, deixando o código mais limpo e legível.
#		- A mensagem de texto que o usuário recebe ao finalizar a execução do
# script foi modificada afim de tornar-se mais amigável e inteligível.
#		- O comando head foi substituído pelo uso da técnica HERE DOCUMENT
# em conjunto com o comando cat na criação do texto padrão do cabeçalho.
#
# Versão 0.4 - 09/07/2008:
#		- Definição das variáveis para gerenciamento do nome dinâmico dos
# scripts criados apenas com o cabeçalho padrão.
#		- Criação da função adiciona_cabecalho()  para verificação do 
# parâmetro passado para o script.
#
# Versão 0.5 - 10/07/2008:
#		- Criação dos códigos de erro.
#		- Codificação da função mensagem() para centralizar a manipulação das
# mensagens enviadas para o usuário.
#		- Adicionado o teste de verficação da existência de um outro cabeçalho
# nos scripts não-vazios.
#
# Versão 0.6 - 11/07/2008:
#		- Remoção da função adiciona_cabecalho() em detrimento da criação de
# outras opções de linha de comando com modificadores.
#		- Criação das chaves -a e --add para indicar adição do cabeçalho a um 
# script pré-existente.
#		- Criação das chaves -p e --preview para indicar que usuário apenas 
# deseja ver como ficará seu arquivo após a adição.
#		- Adicionados os códigos de verificação dos parâmetros -a e -p.
#
# Versão 0.7 - 11/07/2008:
#		- Corrigido o bug da função extrai_versao(), que confundia o
# conteúdo desse cabecalho com o texto padrão existente na variável 
# $ARQUIVO_TEMPORARIO.
#		- Corrigidas as referências aos scripts pré-existentes tratados pelo
# programa através da checagem das chaves.
#		- Corrigido o bug na verificação de cabeçalhos pré-existentes criando
# a função verifica_cabecalho().
#
# Versão 0.8 - 15/07/2008:
#		- Adicionada a verificação de existência dos scripts passados como
# parâmetro para as chaves -a e -p no sistema de arquivos.
#		- Criação da função processa_cabecalho() que centraliza as ações de
# adição ou prévia de cabeçalho para arquivos, eliminando repetição de código
# nas verificações ao final do script.
#		- Criação das caixas de texto explicativas no topo das funções 
# auxiliares.
#
# Versão 0.9 - 17/07/2008:
#		- Adicionada verificação de existência do parâmetro da opção -p dentro
# do sistema de arquivos.
#		- Função verifica_cabecalho() modificada para reconhecer cabeçalhos
# pré-existentes (Bash e Ksh) nos scripts passados como parâmetro para as
# opções -a e -p.
#
# Agradecimentos:
#
# Licença: GPL
#
# ------------------------------------------------------------------------------


# -------------------------[ Definição de variáveis ]---------------------------


### Padrões de nome para scripts vazios
PADRAO_FIXO="scriptNovo"
PADRAO_VARIAVEL=$(date +%d%m%Y-%H%M%S)

### Padronização de nome para scripts vazios
SCRIPT_NOVO=${PADRAO_FIXO}_${PADRAO_VARIAVEL}.ksh

### Arquivos temporários para movimentação dos dados do cabeçalho
ARQUIVO_TEMPORARIO=/tmp/arquivo_cabecalho_temporario.ksh
TEMPORARIO_SED=/tmp/arquivo_temporario_sed.ksh

### Chaves de ativação
PREVIA=0						# Pré-visualizar o script?
ARQUIVO=0						# Já existe cabeçalho no arquivo?

### Códigos de erro
ERRO_CABECALHO_EXISTENTE=10		# O arquivo já possui um cabeçalho
ERRO_OPCAO_INVALIDA=11			# Alguma opção passada é inválida 
ERRO_CHAVE_ADD=12				# Faltou o argumento para a chave -a
ERRO_CHAVE_PREVIEW=13			# Faltou o argumento para a chave -p

### Definição do modo de uso
MODO_USO="
Modo de usar: $(basename "$0") [OPÇÕES | MODIFICADORES arquivo]

OPÇÕES:
	-h, --help      Mostra essa tela de ajuda e sai.
	-V, --version	Mostra a versão do programa e sai.

MODIFICADORES:
	-a, --add       Adiciona o cabeçalho a um arquivo já existente.
	-p, --preview	Prévia do script após a adição do cabeçalho \
(ATENÇÃO: Nenhum arquivo
	                é criado quando essa opção é selecionada).
"


# ---------------------------[ Funções auxiliares ]-----------------------------


################################################################################
#																			   #
# Extrai a versão do script diretamente do cabeçalho.						   #
#																			   #
# A função não recebe parâmetros. O script inteiro é verificado em busca de um #
# padrão que é tratado e mostrado como número da versão.					   #
#																			   #
################################################################################
extrai_versao(){

	echo $(basename "$0" ; \
		 grep "^# Versão " $0 \
		 | tail -1 \
		 | cut -d - -f 1 \
		 | tr -d \#)

	exit 0

}


################################################################################
#																			   #
# Mostra uma mensagem de texto após a execução do Script.					   #
#																			   #
# A função recebe um parâmetro. Esse parâmetro é o script que sofreu as		   #
# modificações de cabeçalho.												   #
#																			   #
################################################################################
mensagem(){

	echo "\n#================================================"
	echo "# Cabeçalho padrão da SUPCD criado para o script"
	echo "# $1 " 
	echo "#================================================\n"

}


################################################################################
#																			   #
# Verifica se o arquivo já contém um cabeçalho.								   #
#																			   #
# A função recebe um parâmetro. Esse parâmetro é o script que deve sofrer as   #
# modificações de cabeçalho.												   #
#																			   #
# - Se a primeira linha do script passado como parâmetro contiver chamadas	   #
# para interpretadores ksh ou bash, uma mensagem de alerta é enviada para o    #
# usuário. A execução de cabecalho.ksh é interrompida e um código de erro	   #
# específico é lançado.														   #
#																			   #
################################################################################
verifica_cabecalho(){

	if head -n 1 "$1" | grep -q "^#!.*bash"
	then
		echo "\nERRO: O arquivo $1 já possui um cabeçalho usando o Bash."
		echo "Remova-o manualmente e execute $(basename "$0") novamente.\n"

		exit $ERRO_CABECALHO_EXISTENTE
	elif head -n 1 "$1" | grep -q "^#!.*ksh"
	then
		echo "\nERRO: O arquivo $1 já possui um cabeçalho usando o Ksh."
		echo "Remova-o manualmente e execute $(basename "$0") novamente.\n"

		exit $ERRO_CABECALHO_EXISTENTE
	fi

}


################################################################################
#																			   #
# Processa solicitações de cabeçalho (adição em arquivo existente ou prévia).  #
#																			   #
# A função recebe dois parâmetros. O primeiro indica o tipo de ação a ser	   #
# realizado e o segundo o arquivo que vai sofrer essa ação.					   #
#																			   #
# - Se o primeiro parâmetro for 1, a ação é de adição do cabeçalho ao arquivo. #
#																			   #
# - Se o primeiro parâmetro for 2, a ação de mostrar a prévia do cabeçalho.	   #
#																			   #
################################################################################
processa_cabecalho(){

	verifica_cabecalho $2
	cat $2 >> $ARQUIVO_TEMPORARIO

	if [ "$1" = 1 ]
	then
		mv $ARQUIVO_TEMPORARIO $2
		mensagem $2
	elif [ "$1" = 2 ]
	then
		more -d $ARQUIVO_TEMPORARIO
		rm $ARQUIVO_TEMPORARIO
	fi

	exit 0

}


#-----------------[ Tratamento de opções de linha de comando ]------------------

### O loop trata todas as opções não-vazias que encontrar
while [ -n "$1" ]
do
	case "$1" in

		-a | --add)
			shift
			ARQUIVO=1
			ARQUIVO_PARAM="$1"

			### Se o arquivo não existe no sistema, será criado. 
			if [ ! -f "$ARQUIVO_PARAM" ]
			then
				echo "\nAVISO: O arquivo $ARQUIVO_PARAM não existe no sistema"
				echo "e será criado agora."
				echo "Certifique-se de que você tem privilégios suficientes"
				echo "para escrever nesse local.\n"

				> $ARQUIVO_PARAM
			fi

			### Verifica se o parâmetro da opção -a é vazio
			if [ -z "$ARQUIVO_PARAM" ]
			then
				echo "\nERRO: Faltou o argumento para a opção -a.\n"

				exit $ERRO_CHAVE_ADD
			fi
		;;

		-p | --preview)
			shift
			PREVIA=1
			PREVIA_PARAM="$1"

			### Se o arquivo não existe no sistema, um erro é retornado.
			if [ ! -f "$PREVIA_PARAM" ]
			then
				echo "\nAVISO: O arquivo $PREVIA_PARAM não existe.\n"
				echo "Para realizar uma prévia, informe um nome"
				echo "de arquivo válido.\n"

				exit $ERRO_CHAVE_PREVIEW
			fi

			### Verifica se o parâmetro da opção -p é vazio
			if [ -z "$PREVIA_PARAM" ]
			then
				echo "\nERRO: Faltou o argumento para a opção -p.\n"

				exit $ERRO_CHAVE_PREVIEW
			fi
		;;

		-h | --help)
			echo "$MODO_USO"

			exit 0
		;;

		-V | --version)
			extrai_versao
		;;

		*)
			echo "\nERRO: A opção $1 não é válida."
			echo "$MODO_USO"

			exit $ERRO_OPCAO_INVALIDA
		;;
	esac

	shift   # Processa as próximas opções
done


# -----------------------------[ Processamento ]--------------------------------


### TODO: Preencher o campo Nome do programa com o parâmetro passado pelo
### usuário nas chaves -a e -p.

### Preenche $ARQUIVO_TEMPORARIO com o conteúdo do cabeçalho padrão
(
cat <<EOF
#!/usr/bin/ksh
# ------------------------------------------------------------------------------
#
# SERPRO - Serviço Federal de Processamento de Dados - Regional Brasília
# Superintendência: CDSUT/SUPCD/CDSXB
#
# Nome do programa:
#
# Site:
#
# Descrição abreviada de funcionalidade:
#
# Autor(es): Desenvolvedor 1 <desenvolvedor1@email>
#			 Desenvolvedor 2 <desenvolvedor2@email>
#
# Data de criação do programa: 00/00/0000 
#
# ------------------------------------------------------------------------------
#
# Descrição detalhada de funcionalidade:
#
# Exemplo(s):
#	$ exemplo_de_execucao.ksh param1 param2 ... 
#	$ 
#
# ------------------------------------------------------------------------------
#
# Lista de Modificações
#
# Autor: Desenvolvedor 1 <desenvolvedor1@email>
#
# Versao 0.1 - 00/00/0000:
#       - Descrição abreviada de uma modificação curta.
#       - Descrição abreviada de uma modificação maior, que, embora possua mais
# informações, pode sofrer quebras de linhas para não ultrapassar a coluna 80.
#
# Autor: Desenvolvedor 2 <desenvolvedor2@email>
#
# Versao 0.2 - 00/00/0000:
#       - Modificações realizadas por outro desenvolvedor.
#
# Agradecimentos:
#
# Licença:
#
# ------------------------------------------------------------------------------

EOF
) > $ARQUIVO_TEMPORARIO


### Correção do bug da função extrai_versao()
sed "s/Versao/Versão/g" $ARQUIVO_TEMPORARIO > $TEMPORARIO_SED
cat $TEMPORARIO_SED > $ARQUIVO_TEMPORARIO
rm $TEMPORARIO_SED


### Se o arquivo já existe, adiciona o cabeçalho sem modificar o conteúdo.
if [ "$ARQUIVO" = 1 ]
then
	processa_cabecalho 1 $ARQUIVO_PARAM
fi


### Verifica se a solicitação é apenas uma prévia
if [ "$PREVIA" = 1 ]
then
	processa_cabecalho 2 $PREVIA_PARAM
fi


### Nenhuma chave foi ativada. O cabeçalho é adicionado a um arquivo vazio.
mv $ARQUIVO_TEMPORARIO ./$SCRIPT_NOVO
mensagem $SCRIPT_NOVO

